import { createAnthropic } from '@augment/chat-model';
import { Session, ModelProvider, SendRequest, StructuredNode, NodeType, TurnStatus } from '@augment/chat-core';
import { ToolManager, ToolExecutionContext, ToolResult, ToolCategory } from '@augment/tools';
import Anthropic from '@anthropic-ai/sdk';
import { Logger, LogLevel, ErrorHandler, ErrorCode } from './error-handling';
import { ToolExecutionCoordinator, ToolExecutionEvent } from './tool-execution-coordinator';

// 重新导出核心组件供外部使用
export { Logger, LogLevel, ErrorHandler, ErrorCode } from './error-handling';
export { ToolExecutionCoordinator, ToolExecutionEvent } from './tool-execution-coordinator';

/**
 * 升级版 LLM 模型提供者 - 集成了完整的工具管理和错误处理系统
 */
export class LlmModelProvider implements ModelProvider {
    private anthropic: Anthropic;
    private cancelledRequests = new Set<string>();
    private toolManager: ToolManager;
    private toolCoordinator: ToolExecutionCoordinator;
    private logger: Logger;
    private errorHandler: ErrorHandler;
    private initialized: boolean = false;

    constructor(
        apiKey: string,
        private modelName: string = 'qwen3-coder-plus',
        logLevel: LogLevel = LogLevel.INFO
    ) {
        this.logger = new Logger(logLevel);
        this.errorHandler = new ErrorHandler(this.logger);
        this.anthropic = createAnthropic('qwen', apiKey);
        this.toolManager = new ToolManager(this.logger);
        this.toolCoordinator = new ToolExecutionCoordinator(this.toolManager, this.logger);

        this.setupEventListeners();
    }

    /**
     * 设置事件监听器
     */
    private setupEventListeners(): void {
        this.toolCoordinator.on('tool-start', (event: ToolExecutionEvent) => {
            this.logger.info(`Tool execution started: ${event.toolName}`, { requestId: event.requestId });
        });

        this.toolCoordinator.on('tool-complete', (event: ToolExecutionEvent) => {
            this.logger.info(`Tool execution completed: ${event.toolName}`, {
                requestId: event.requestId,
                data: event.data
            });
        });

        this.toolCoordinator.on('tool-error', (event: ToolExecutionEvent) => {
            this.logger.error(`Tool execution failed: ${event.toolName}`, event.error);
        });
    }

    /**
     * 初始化工具系统
     */
    async initialize(): Promise<void> {
        if (this.initialized) {
            this.logger.warn('LlmModelProvider is already initialized');
            return;
        }

        try {
            this.logger.info('Initializing LlmModelProvider...');

            await this.toolManager.initialize();

            this.initialized = true;
            this.logger.info('LlmModelProvider initialized successfully with tools:',
                this.toolManager.getAvailableTools());

        } catch (error) {
            const augmentError = this.errorHandler.handleError(error as Error, {
                code: ErrorCode.INITIALIZATION_FAILED,
                context: { component: 'LlmModelProvider' }
            });
            throw augmentError;
        }
    }

    /**
     * 获取可用工具列表（Anthropic API 格式）
     */
    private getAnthropicTools(): any[] {
        const availableTools = this.toolManager.getAvailableTools();
        const anthropicTools: any[] = [];

        // 文件操作工具
        if (availableTools.includes('read-file')) {
            anthropicTools.push({
                name: 'read-file',
                description: 'Read content from a file with encoding support',
                input_schema: {
                    type: 'object',
                    properties: {
                        path: { type: 'string', description: 'File path to read' },
                        encoding: { type: 'string', description: 'File encoding (default: utf8)' }
                    },
                    required: ['path']
                }
            });
        }

        if (availableTools.includes('save-file')) {
            anthropicTools.push({
                name: 'save-file',
                description: 'Save content to a file with encoding and formatting options',
                input_schema: {
                    type: 'object',
                    properties: {
                        path: { type: 'string', description: 'File path to save' },
                        content: { type: 'string', description: 'Content to save' },
                        encoding: { type: 'string', description: 'File encoding (default: utf8)' },
                        add_last_line_newline: { type: 'boolean', description: 'Add newline at end (default: true)' }
                    },
                    required: ['path', 'content']
                }
            });
        }

        if (availableTools.includes('str-replace-editor')) {
            anthropicTools.push({
                name: 'str-replace-editor',
                description: 'Edit file by replacing specific text with line number precision',
                input_schema: {
                    type: 'object',
                    properties: {
                        path: { type: 'string', description: 'File path to edit' },
                        old_str: { type: 'string', description: 'Text to replace' },
                        new_str: { type: 'string', description: 'Replacement text' },
                        old_str_start_line_number: { type: 'number', description: 'Start line number' },
                        old_str_end_line_number: { type: 'number', description: 'End line number' }
                    },
                    required: ['path', 'old_str', 'new_str', 'old_str_start_line_number', 'old_str_end_line_number']
                }
            });
        }

        // 进程管理工具
        if (availableTools.includes('launch-process')) {
            anthropicTools.push({
                name: 'launch-process',
                description: 'Launch a system process with comprehensive control options',
                input_schema: {
                    type: 'object',
                    properties: {
                        command: { type: 'string', description: 'Command to execute' },
                        wait: { type: 'boolean', description: 'Whether to wait for completion' },
                        max_wait_seconds: { type: 'number', description: 'Maximum wait time in seconds' },
                        cwd: { type: 'string', description: 'Working directory' }
                    },
                    required: ['command', 'wait', 'max_wait_seconds', 'cwd']
                }
            });
        }

        if (availableTools.includes('kill-process')) {
            anthropicTools.push({
                name: 'kill-process',
                description: 'Kill a running process by terminal ID',
                input_schema: {
                    type: 'object',
                    properties: {
                        terminal_id: { type: 'number', description: 'Terminal ID of the process to kill' }
                    },
                    required: ['terminal_id']
                }
            });
        }

        if (availableTools.includes('read-process')) {
            anthropicTools.push({
                name: 'read-process',
                description: 'Read output from a running process',
                input_schema: {
                    type: 'object',
                    properties: {
                        terminal_id: { type: 'number', description: 'Terminal ID of the process' },
                        wait: { type: 'boolean', description: 'Whether to wait for completion' },
                        max_wait_seconds: { type: 'number', description: 'Maximum wait time in seconds' }
                    },
                    required: ['terminal_id', 'wait', 'max_wait_seconds']
                }
            });
        }

        if (availableTools.includes('write-process')) {
            anthropicTools.push({
                name: 'write-process',
                description: 'Write input to a running process',
                input_schema: {
                    type: 'object',
                    properties: {
                        terminal_id: { type: 'number', description: 'Terminal ID of the process' },
                        input_text: { type: 'string', description: 'Text to write to the process' }
                    },
                    required: ['terminal_id', 'input_text']
                }
            });
        }

        if (availableTools.includes('list-processes')) {
            anthropicTools.push({
                name: 'list-processes',
                description: 'List all running processes with their status',
                input_schema: {
                    type: 'object',
                    properties: {},
                    required: []
                }
            });
        }

        // 记忆管理工具
        if (availableTools.includes('remember')) {
            anthropicTools.push({
                name: 'remember',
                description: 'Create a persistent memory item for future reference',
                input_schema: {
                    type: 'object',
                    properties: {
                        memory: { type: 'string', description: 'Content to remember' }
                    },
                    required: ['memory']
                }
            });
        }

        if (availableTools.includes('memory-retrieval')) {
            anthropicTools.push({
                name: 'memory-retrieval',
                description: 'Retrieve memories based on search query',
                input_schema: {
                    type: 'object',
                    properties: {
                        query: { type: 'string', description: 'Search query for memories' },
                        limit: { type: 'number', description: 'Maximum number of results (default: 10)' }
                    },
                    required: ['query']
                }
            });
        }

        return anthropicTools;
    }

    /**
     * 执行工具调用 - 使用协调器进行高级管理
     */
    private async executeToolCall(toolName: string, input: any, requestId: string): Promise<ToolResult> {
        const context: ToolExecutionContext = {
            workspaceRoot: process.cwd(),
            environment: process.env as Record<string, string>,
            timestamp: new Date(),
            permissions: this.getPermissionsForTool(toolName),
            logger: this.logger
        };

        try {
            // 预处理参数
            const processedInput = this.preprocessToolInput(toolName, input, context);

            // 使用协调器执行工具
            const response = await this.toolCoordinator.executeToolAsync({
                requestId,
                toolName,
                parameters: processedInput,
                context,
                priority: this.getToolPriority(toolName),
                timeout: this.getToolTimeout(toolName)
            });

            this.logger.info(`Tool ${toolName} executed successfully`, {
                requestId,
                success: response.result.success,
                executionTime: response.executionTime
            });

            return response.result;

        } catch (error) {
            this.logger.error(`Tool ${toolName} execution failed:`, error as Record<string, any>);
            return {
                success: false,
                error: {
                    code: 'EXECUTION_FAILED',
                    message: error instanceof Error ? error.message : `${error}`
                }
            };
        }
    }

    /**
     * 预处理工具输入参数
     */
    private preprocessToolInput(toolName: string, input: any, context: ToolExecutionContext): any {
        const processedInput = { ...input };

        // 为 launch-process 工具添加默认参数
        if (toolName === 'launch-process') {
            processedInput.wait = processedInput.wait !== undefined ? processedInput.wait : true;
            processedInput.max_wait_seconds = processedInput.max_wait_seconds !== undefined ? processedInput.max_wait_seconds : 30;
            processedInput.cwd = processedInput.cwd !== undefined ? processedInput.cwd : context.workspaceRoot;
        }

        // 为 memory-retrieval 工具添加默认参数
        if (toolName === 'memory-retrieval') {
            processedInput.limit = processedInput.limit !== undefined ? processedInput.limit : 10;
        }

        // 为 remember 工具处理参数格式
        if (toolName === 'remember' && input.content) {
            processedInput.memory = input.content;
            delete processedInput.content;
        }

        return processedInput;
    }

    /**
     * 获取工具优先级
     */
    private getToolPriority(toolName: string): number {
        // 文件操作工具优先级较高
        if (['read-file', 'save-file', 'str-replace-editor'].includes(toolName)) {
            return 8;
        }

        // 进程管理工具优先级中等
        if (toolName.includes('process')) {
            return 6;
        }

        // 记忆工具优先级较低
        if (['remember', 'memory-retrieval'].includes(toolName)) {
            return 4;
        }

        return 5; // 默认优先级
    }

    /**
     * 获取工具超时时间
     */
    private getToolTimeout(toolName: string): number {
        // 进程工具可能需要更长时间
        if (toolName.includes('process')) {
            return 60000; // 60秒
        }

        // 文件操作通常较快
        if (toolName.includes('file')) {
            return 10000; // 10秒
        }

        return 30000; // 默认30秒
    }

    private getPermissionsForTool(toolName: string): string[] {
        const permissions: string[] = [];

        if (toolName.includes('file') || toolName === 'read-file' || toolName === 'save-file') {
            permissions.push('file:read', 'file:write');
        }

        if (toolName.includes('process') || toolName === 'launch-process') {
            permissions.push('process:execute', 'process:read', 'process:write', 'process:kill');
        }

        return permissions;
    }

    /**
     * 格式化工具执行结果 - 增强版本
     */
    private formatToolResult(toolName: string, result: ToolResult): string {
        if (!result.success) {
            return `❌ 工具 ${toolName} 执行失败: ${result.error?.message || '未知错误'}`;
        }

        switch (toolName) {
            case 'read-file':
                if (result.data?.content) {
                    const content = result.data.content;
                    const preview = content.length > 500 ? content.substring(0, 500) + '...' : content;
                    return `📄 文件读取成功 (${result.data.size || content.length} 字符):\n\`\`\`\n${preview}\n\`\`\``;
                }
                return `✅ 文件读取成功`;

            case 'save-file':
                return `✅ 文件保存成功: ${result.data?.path || ''}`;

            case 'str-replace-editor':
                return `✅ 文件编辑成功: 替换了 ${result.data?.linesReplaced || 0} 行`;

            case 'launch-process':
                if (result.data?.terminal_id) {
                    const output = result.data.output ? `\n输出:\n\`\`\`\n${result.data.output}\n\`\`\`` : '';
                    const error = result.data.error ? `\n错误:\n\`\`\`\n${result.data.error}\n\`\`\`` : '';
                    return `🚀 进程启动成功 (终端ID: ${result.data.terminal_id})${output}${error}`;
                }
                return `✅ 进程执行成功`;

            case 'kill-process':
                return `🛑 进程终止成功: ${result.data?.message || ''}`;

            case 'read-process':
                const output = result.data?.output ? `\n输出:\n\`\`\`\n${result.data.output}\n\`\`\`` : '';
                const error = result.data?.error ? `\n错误:\n\`\`\`\n${result.data.error}\n\`\`\`` : '';
                return `� 进程输出读取成功${output}${error}`;

            case 'write-process':
                return `✍️ 进程输入写入成功: ${result.data?.message || ''}`;

            case 'list-processes':
                const processes = result.data?.processes || [];
                const processInfo = processes.map((p: any) =>
                    `- 终端ID: ${p.terminal_id}, 状态: ${p.completed ? '已完成' : '运行中'}`
                ).join('\n');
                return `📋 进程列表 (${processes.length} 个进程):\n${processInfo}`;

            case 'remember':
                return `💾 记忆创建成功: ${result.data?.message || ''}`;

            case 'memory-retrieval':
                const memories = result.data?.results || [];
                const memoryInfo = memories.slice(0, 3).map((m: any) =>
                    `- ${m.content.substring(0, 100)}${m.content.length > 100 ? '...' : ''}`
                ).join('\n');
                const moreInfo = memories.length > 3 ? `\n... 还有 ${memories.length - 3} 条记忆` : '';
                return `🧠 找到 ${memories.length} 条相关记忆:\n${memoryInfo}${moreInfo}`;

            default:
                return `✅ 工具 ${toolName} 执行成功`;
        }
    }

    /**
     * 生成响应 - 升级版本，包含初始化检查和增强错误处理
     */
    async *generate(req: SendRequest & { requestId: string }): AsyncIterable<StructuredNode> {
        const { requestMessage, requestId } = req;

        // 检查是否已初始化
        if (!this.initialized) {
            yield {
                type: NodeType.RawResponse,
                ts: Date.now(),
                requestId,
                text: '❌ 扩展未初始化，请先调用 initialize() 方法'
            };
            return;
        }

        try {
            // 发送思考节点
            yield {
                type: NodeType.Thinking,
                ts: Date.now(),
                requestId,
                text: 'Analyzing request and preparing advanced tools...'
            };

            // 检查是否被取消
            if (this.cancelledRequests.has(requestId)) {
                return;
            }

            // 调用 Anthropic API 使用增强配置
            const response = await this.anthropic.messages.create({
                max_tokens: 4096,
                messages: [
                    { role: 'user', content: requestMessage }
                ],
                model: this.modelName,
                temperature: 0.7,
                tools: this.getAnthropicTools()
            });

            // 处理响应内容
            for (const content of response.content) {
                if (this.cancelledRequests.has(requestId)) {
                    return;
                }

                if (content.type === 'text') {
                    // 发送文本响应节点
                    yield {
                        type: NodeType.RawResponse,
                        ts: Date.now(),
                        requestId,
                        text: content.text
                    };
                } else if (content.type === 'tool_use') {
                    // 发送工具使用节点
                    yield {
                        type: NodeType.ToolUse,
                        ts: Date.now(),
                        requestId,
                        tool: content.name,
                        input: content.input
                    };

                    // 执行工具并返回结果
                    try {
                        const toolResult = await this.executeToolCall(content.name, content.input, requestId);

                        // 发送工具执行结果作为文本响应
                        if (toolResult.success) {
                            const resultText = this.formatToolResult(content.name, toolResult);
                            yield {
                                type: NodeType.RawResponse,
                                ts: Date.now(),
                                requestId,
                                text: resultText
                            };
                        } else {
                            yield {
                                type: NodeType.RawResponse,
                                ts: Date.now(),
                                requestId,
                                text: `工具执行失败: ${toolResult.error?.message || '未知错误'}`
                            };
                        }
                    } catch (error) {
                        yield {
                            type: NodeType.RawResponse,
                            ts: Date.now(),
                            requestId,
                            text: `工具执行异常: ${error instanceof Error ? error.message : '未知错误'}`
                        };
                    }
                }
            }

            // 生成智能建议问题
            yield {
                type: NodeType.SuggestedQuestions,
                ts: Date.now(),
                requestId,
                questions: ['继续解释', '举个例子', '还有其他方法吗？', '查看相关记忆', '显示工具统计']
            };

            // 标记主文本完成
            yield {
                type: NodeType.MainTextFinished,
                ts: Date.now(),
                requestId
            };

        } catch (error) {
            this.logger.error('Generation error:', error as Record<string, any>);

            const augmentError = this.errorHandler.handleError(error as Error, {
                code: ErrorCode.API_REQUEST_FAILED,
                context: { requestId, component: 'LlmModelProvider.generate' }
            });

            yield {
                type: NodeType.RawResponse,
                ts: Date.now(),
                requestId,
                text: `错误: ${augmentError.message}`
            };

            yield {
                type: NodeType.MainTextFinished,
                ts: Date.now(),
                requestId
            };
        } finally {
            this.cancelledRequests.delete(requestId);
        }
    }

    /**
     * 取消请求
     */
    cancel(requestId: string): void {
        this.cancelledRequests.add(requestId);
        this.logger.info(`Request ${requestId} cancelled`);
    }

    /**
     * 获取工具统计信息
     */
    getToolStats(): any {
        return this.toolManager.getToolStats();
    }

    /**
     * 启用/禁用工具
     */
    setToolEnabled(toolName: string, enabled: boolean): boolean {
        return this.toolManager.setToolEnabled(toolName, enabled);
    }

    /**
     * 检查工具是否可用
     */
    isToolAvailable(toolName: string): boolean {
        return this.toolManager.isToolAvailable(toolName);
    }

    /**
     * 获取可用工具列表
     */
    getAvailableTools(): string[] {
        return this.toolManager.getAvailableTools();
    }

    /**
     * 按类别获取工具
     */
    getToolsByCategory(category: ToolCategory): string[] {
        return this.toolManager.getToolsByCategory(category);
    }

    /**
     * 获取协调器状态
     */
    getCoordinatorStatus(): any {
        return this.toolCoordinator.getExecutionStats();
    }

    /**
     * 设置最大并发工具执行数
     */
    setMaxConcurrentExecutions(max: number): void {
        this.toolCoordinator.setMaxConcurrentExecutions(max);
    }

    /**
     * 清理资源 - 增强版本
     */
    async dispose(): Promise<void> {
        try {
            this.logger.info('Disposing LlmModelProvider...');

            // 取消所有活跃请求
            for (const requestId of this.cancelledRequests) {
                this.cancel(requestId);
            }

            // 清理工具管理器和协调器
            await this.toolManager.cleanup();
            await this.toolCoordinator.cleanup();

            this.cancelledRequests.clear();
            this.initialized = false;

            this.logger.info('LlmModelProvider disposed successfully');
        } catch (error) {
            this.logger.error('Failed to dispose LlmModelProvider:', error as Record<string, any>);
        }
    }
}
/**
 * 升级版演示函数 - 展示新架构的高级功能
 */
async function demonstrateUpgradedExtension() {
    try {
        console.log('🚀 启动升级后的 Augment 扩展演示...\n');

        // 创建升级版模型提供者
        const modelProvider = new LlmModelProvider(
            `sk-dc6fc4f316aa4968888d38fff8fa94b7`,
            'qwen3-coder-plus',
            LogLevel.INFO
        );

        // 显式初始化
        await modelProvider.initialize();

        console.log('📊 工具统计:', modelProvider.getToolStats());
        console.log('🔧 可用工具:', modelProvider.getAvailableTools());
        console.log('⚙️ 协调器状态:', modelProvider.getCoordinatorStatus());

        const session = new Session({
            model: modelProvider
        });

        // 测试文件操作工具
        console.log('\n📝 测试增强文件操作工具...');
        try {
            const fileTestTurnId = await session.send({
                requestMessage: `请帮我创建一个名为 test-output-upgraded.txt 的文件，内容是 "Hello from upgraded qwen extension!"`
            });
            await waitForTurnCompletion(session, fileTestTurnId);
        } catch (error) {
            console.error('文件操作测试失败:', error);
        }

        // 测试记忆功能
        console.log('\n🧠 测试记忆管理工具...');
        try {
            const memoryTestTurnId = await session.send({
                requestMessage: `请记住这个信息：今天测试了升级版的 Augment 扩展，使用 qwen 模型，新增了错误处理、日志记录和工具协调功能`
            });
            await waitForTurnCompletion(session, memoryTestTurnId);
        } catch (error) {
            console.error('记忆功能测试失败:', error);
        }

        // 显示最终统计
        console.log('\n📊 最终统计信息:');
        console.log('- 工具统计:', modelProvider.getToolStats());
        console.log('- 协调器状态:', modelProvider.getCoordinatorStatus());

        // 清理资源
        await modelProvider.dispose();
        console.log('\n✅ 升级版演示完成，资源已清理');

    } catch (error) {
        console.error('❌ 升级版演示失败:', error);
    }
}

/**
 * 工厂函数 - 创建并初始化升级版 LlmModelProvider
 */
export async function createUpgradedLlmProvider(
    apiKey: string,
    options: {
        modelName?: string;
        logLevel?: LogLevel;
        enabledTools?: string[];
        maxConcurrentTools?: number;
    } = {}
): Promise<LlmModelProvider> {
    const {
        modelName = 'qwen3-coder-plus',
        logLevel = LogLevel.INFO,
        enabledTools,
        maxConcurrentTools = 5
    } = options;

    const provider = new LlmModelProvider(apiKey, modelName, logLevel);

    // 初始化提供者
    await provider.initialize();

    // 配置工具
    if (enabledTools) {
        const allTools = provider.getAvailableTools();
        for (const tool of allTools) {
            if (!enabledTools.includes(tool)) {
                provider.setToolEnabled(tool, false);
            }
        }
    }

    // 设置并发限制
    provider.setMaxConcurrentExecutions(maxConcurrentTools);

    return provider;
}

/**
 * 快速启动函数 - 创建会话并返回准备就绪的系统
 */
export async function quickStartUpgraded(
    apiKey: string,
    options: {
        modelName?: string;
        logLevel?: LogLevel;
        enabledTools?: string[];
        maxConcurrentTools?: number;
    } = {}
): Promise<{ provider: LlmModelProvider; session: Session }> {
    const provider = await createUpgradedLlmProvider(apiKey, options);
    const session = new Session({ model: provider });

    return { provider, session };
}

async function waitForTurnCompletion(session: Session, turnId: string) {
    try {
        await new Promise(r => setTimeout(r, 150));
        let turn = session.getTurn(turnId);

        if (!turn) {
            console.log('❌ Turn not found:', turnId);
            return;
        }

        let attempts = 0;
        const maxAttempts = 100; // 15秒超时

        while (turn.status === TurnStatus.Sent && attempts < maxAttempts) {
            turn = session.getTurn(turnId)!;
            await new Promise(r => setTimeout(r, 150));
            attempts++;
        }

        if (attempts >= maxAttempts) {
            console.log('⏰ Turn timed out:', turnId);
            return;
        }

        console.log('✅ Turn completed:', turn.status);

        // 显示响应内容（简化版）
        if (turn.nodes && turn.nodes.length > 0) {
            const textNodes = turn.nodes.filter(node => node.type === NodeType.RawResponse);
            if (textNodes.length > 0) {
                const lastTextNode = textNodes[textNodes.length - 1];
                if (lastTextNode.text) {
                    console.log('📄 Response:', lastTextNode.text.substring(0, 200) + (lastTextNode.text.length > 200 ? '...' : ''));
                }
            }
        }
    } catch (error) {
        console.error('❌ Error waiting for turn completion:', error);
    }
}

// 如果直接运行此文件
if (require.main === module) {
    demonstrateUpgradedExtension();
}